﻿using MimeKit;
using MimeKit.Utils;
using MailKit.Net.Smtp;

namespace D.Util.UtilEmil
{
    /// <summary>
    /// 发送邮件
    /// MailKit
    /// </summary>
    public class EmailUtilMailKit
    {

        private MimeMessage mMailMessage;   //主要处理发送邮件的内容（如：收发人地址、标题、主体、图片等等）
        private int mSenderPort;   //发送邮件所用的端口号（htmp协议默认为25）
        private string mSenderServerHost;    //发件箱的邮件服务器地址（IP形式或字符串形式均可）
        private string mSenderPassword;    //发件箱的密码
        private string mSenderUsername;   //发件箱的用户名（即@符号前面的字符串，例如：hello@163.com，用户名为：hello）
        private bool mEnableSsl;    //是否对邮件内容进行socket层加密传输

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fromMail">发件人地址</param>
        /// <param name="toMail">收件人地址（多个电子邮件地址之间必须用逗号字符（“,”）分隔）</param>
        /// <param name="subject">邮件标题</param>
        /// <param name="emailBody">邮件内容（可以以html格式进行设计）</param>
        /// <param name="username">发件箱的用户名（即@符号前面的字符串，例如：hello@163.com，用户名为：hello）</param>
        /// <param name="password">发件人邮箱密码</param>
        /// <param name="attachments">邮件附件</param>
        /// <param name="sslEnable">对邮件内容进行socket层加密传输，false表示不加密</param>
        /// <param name="port">发送邮件所用的端口号（htmp协议默认为25）</param>
        public EmailUtilMailKit(string fromMail, string subject, string emailBody, string imagePath,
            string username, string password,
           bool sslEnable = false, int port = 25)
        {
            mMailMessage = new MimeMessage();
            mMailMessage.Subject = subject;

            var builder = new BodyBuilder();
            var message = $"当前时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}";
            message += emailBody + "<br />";

            if (!string.IsNullOrWhiteSpace(imagePath))
            {// 携带图片

                var image = builder.LinkedResources.Add(imagePath);
                image.ContentId = MimeUtils.GenerateMessageId();
                message += $"<img src=\"cid:{image.ContentId}\"/>";
            }
 
            mMailMessage.Body = builder.ToMessageBody();
            mSenderServerHost = fromMail;//GetSmtp(fromMail);
            mSenderUsername = username;
            mSenderPassword = password;
            mSenderPort = port;
            mEnableSsl = sslEnable;
        }

        /// <summary>
        /// 获取邮箱SMTP
        /// </summary>
        /// <param name="fromMail"></param>
        /// <returns></returns>
        private static string GetSmtp(string fromMail)
        {
            string result = "";
            if (!string.IsNullOrWhiteSpace(fromMail) && fromMail.IndexOf('@') > 0)
            {
                string ext = fromMail.Substring(fromMail.IndexOf('@') + 1);
                switch (ext)
                {
                    case "163.com":
                        result = "smtp.163.com";
                        break;
                    case "gmail.com":
                        result = "smtp.gmail.com";
                        break;
                    case "qq.com":
                        result = "smtp.qq.com";
                        break;
                    case "sina.com":
                        result = "smtp.sina.com";
                        break;
                }
            }
            return result;
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="list">接收人地址</param>
        /// <returns></returns>
        public async Task SendEmail(string title, List<string> list)
        {
            // 组织接收地址
            var address = new List<MailboxAddress>();
            for (int i = 0; i < list.Count; i++)
            {
                address.Add(new MailboxAddress(title, list[i]));
            }
            mMailMessage.From.Add(new MailboxAddress(title, mSenderUsername));
            mMailMessage.To.AddRange(address);

            using var client = new SmtpClient
            {
                ServerCertificateValidationCallback = (s, c, h, e) => true
            };
            client.AuthenticationMechanisms.Remove("XOAUTH2");

            try
            {
                await client.ConnectAsync(mSenderServerHost, mSenderPort, mEnableSsl);
                await client.AuthenticateAsync(mSenderUsername, mSenderPassword);
                await client.SendAsync(mMailMessage);
                await client.DisconnectAsync(true);
            }
            catch (Exception ex)
            {

            }
        }
    }
}
